/*
 *  Copyright 2005 Blandware (http://www.blandware.com)
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.blandware.atleap.service.forum;

import com.blandware.atleap.common.util.PartialCollection;
import com.blandware.atleap.common.util.QueryInfo;
import com.blandware.atleap.model.forum.Forum;
import com.blandware.atleap.model.forum.ForumSubscription;
import com.blandware.atleap.model.forum.Post;
import com.blandware.atleap.model.forum.Topic;
import com.blandware.atleap.persistence.exception.DeleteException;
import com.blandware.atleap.persistence.exception.UpdateException;
import com.blandware.atleap.service.core.BaseManager;
import com.blandware.atleap.service.exception.BeanAlreadyExistsException;
import com.blandware.atleap.service.exception.BeanNotFoundException;
import com.blandware.atleap.service.exception.OwnerNotFoundException;

import java.util.List;
import java.util.Map;

/**
 * <p>Business Delegate (Proxy) Interface to handle communication between web
 * and persistence layer.
 * </p>
 * <p><a href="ForumManager.java.html"><i>View source</i></a></p>
 *
 * @author Roman Puchkovskiy <a href="mailto:roman.puchkovskiy@blandware.com">
 *         &lt;roman.puchkovskiy@blandware.com&gt;</a>
 * @version $Revision: 1.4 $ $Date: 2006/10/31 11:55:53 $
 */
public interface ForumManager extends BaseManager {

    //  F O R U M S

    // ~ CRUD methods ================================================================

    /**
     * Creates a new forum in a parent forum. If parentId is null, forum is
     * created in root.
     *
     * @param forum forum to create
     * @param parentId ID of parent forum
     * @param contentLocaleIdentifier identifier of content locale representing
     * forum language
     * @param linkedObjects map of pairs <code>uri -&gt; object<code>, which
     * link URI in the annotation to corresponding object (resource or page) if
     * it exists
     * @return ID of created forum
     * @throws BeanNotFoundException thrown if no forum with such ID exists
     * @throws BeanAlreadyExistsException thrown if a duplicate already exists
     */
    public Long createForum(Forum forum, Long parentId,
                            String contentLocaleIdentifier, Map linkedObjects)
            throws BeanNotFoundException, BeanAlreadyExistsException;

	/**
	 * Retrieves forum with specified ID.
	 *
	 * @param forumId the ID of forum to retrieve
	 * @return Forum or null if no forum with specified ID exists in database
	 */
	public Forum retrieveForum(Long forumId);

	/**
	 * Updates a forum.
	 *
	 * @param forum         Forum to update
	 * @param parentId ID of parent forum
     * @param linkedObjects map of pairs <code>uri -&gt; object<code>, which
     * link URI in the annotation to corresponding object (resource or page) if
     * it exists
	 * @throws BeanNotFoundException      if parent forum with specified ID
     * couldn't be found
	 * @throws BeanAlreadyExistsException if a duplicate already exists
	 */
	public void updateForum(Forum forum, Long parentId, Map linkedObjects)
            throws BeanNotFoundException, BeanAlreadyExistsException;

	/**
	 * Updates a forum while not touching parent and linked objects.
	 *
	 * @param forum         Forum to update
	 * @throws BeanNotFoundException      if parent forum with specified ID
     * couldn't be found
	 * @throws BeanAlreadyExistsException if a duplicate already exists
	 */
	public void updateForum(Forum forum)
            throws BeanNotFoundException, BeanAlreadyExistsException;

	/**
	 * Removes a forum.
	 *
	 * @param forumId ID of forum to remove
	 * @throws BeanNotFoundException thrown if forum with specified ID couldn't
     * be found
	 * @throws com.blandware.atleap.persistence.exception.DeleteException thrown
     * if forum cannot be deleted
	 */
	public void deleteForum(Long forumId) throws BeanNotFoundException,
            DeleteException;

	// ~ Additional methods ================================================================

	/**
	 * Retrieves filtered/sorted collection of forums.
	 *
	 * @param queryInfo Object that contains information about how to filter
     * and sort data
	 * @return Collection of forums
	 */
	public PartialCollection listForums(QueryInfo queryInfo);

    /**
     * Changes a forum position so that it becomes one position higher or lower.
     *
     * @param forum what forum to move
     * @param up if true, forum is moved up, else down
     */
    public void moveForum(Forum forum, boolean up);

    /**
     * Returns least and most positions of forum which parent has given ID. If
     * parentId is <code>null</code>, then root forums are considered.
     *
     * @param parentId ID of forum which children will be considered
     * @return two-element array: least and most occupied positions
     */
    public Integer[] getFirstLastForumOccupiedPositions(Long parentId);

    //  T O P I C S

    // ~ CRUD methods ================================================================

    /**
     * Creates a topic in a forum with given ID assigning its first post.
     *
     * @param topic topic to create
     * @param forumId topic owner ID
     * @param firstPost post which begins this topic
     * @return ID of created topic
     */
    public Long createTopic(Topic topic, Long forumId, Post firstPost)
            throws OwnerNotFoundException, BeanAlreadyExistsException;

    /**
     * Retrieves a topic by its ID.
     *
     * @param topicId ID of topic to retrieve
     * @return found topic
     */
    public Topic retrieveTopic(Long topicId);

    /**
     * Deletes a topic with a given ID.
     *
     * @param topicId ID of topic to delete
     */
    public void deleteTopic(Long topicId) throws BeanNotFoundException;

    // ~ Additional methods ================================================================

	/**
	 * Retrieves filtered/sorted collection of topics.
	 *
	 * @param queryInfo Object that contains information about how to filter
     * and sort data
	 * @return Collection of topics
	 */
    public PartialCollection listTopics(QueryInfo queryInfo);

    //  P O S T S

    // ~ CRUD methods ================================================================

    /**
     * Creates a post in a topic with given ID.
     *
     * @param post post to create
     * @param topicId post owner ID
     * @return ID of created post
     */
    public Long createPost(Post post, Long topicId)
            throws OwnerNotFoundException, BeanAlreadyExistsException;

    /**
     * Retrieves a post by its ID.
     *
     * @param postId ID of post to retrieve
     * @return found post
     */
    public Post retrievePost(Long postId);

    /**
     * Updates a post.
     *
     * @param post post to be updated
     * @param topicId ID of topic to which post belongs
     */
    public void updatePost(Post post, Long topicId)
            throws OwnerNotFoundException;

    /**
     * Updates a post leaving its parent topic unchanged.
     *
     * @param post post to be updated
     */
    public void updatePost(Post post) throws OwnerNotFoundException;

    /**
     * Deletes a post with a given ID.
     *
     * @param postId ID of post to delete
     */
    public void deletePost(Long postId) throws BeanNotFoundException,
            DeleteException;

    // ~ Additional methods ================================================================

    /**
     * Retrieves filtered/sorted collection of posts
     *
     * @param queryInfo Object that contains information about how to filter
     * and sort data
     * @return Collection of posts
     */
    public PartialCollection listPosts(QueryInfo queryInfo);

    //  F O R U M   S U B S C R I P T I O N S

    // ~ CRUD methods ================================================================

    /**
     * Creates a subscription to forum or topic.
     *
     * @param forumSubscription subscription to create
     * @param forumId ID of forum to which subscription is created
     * @param topicId ID of topic to which subscription is created
     * @param userName identifies a user who creates a subscription
     * @return subscription ID
     */
    public Long createSubscription(ForumSubscription forumSubscription,
                                   Long forumId, Long topicId, String userName)
            throws OwnerNotFoundException, BeanAlreadyExistsException;

    /**
     * Deletes a subscription by its ID. Also, check is made that its token
     * is equal to a given one.
     *
     * @param id subscription ID
     * @param token token to check
     */
    public void deleteSubscription(Long id, String token)
            throws BeanNotFoundException, DeleteException;

    /**
     * Deletes a subscription by forum or topic ID and username.
     *
     * @param forumId ID of forum
     * @param topicId ID of topic
     * @param userName user name
     */
    public void deleteSubscription(Long forumId, Long topicId, String userName)
            throws DeleteException, BeanNotFoundException;

    // ~ Additional methods ================================================================

    /**
     * Deletes a subscription by its ID. Also, check is made that its token
     * is equal to a given one.
     *
     * @param id subscription ID
     * @param token token to check
     */
    public void activateSubscription(Long id, String token)
            throws BeanNotFoundException, UpdateException;

    /**
     * Returns a list of active subcriptions to a given forum or topic.
     *
     * @param forumId forum ID
     * @param topicId topic ID
     * @return list of active subcriptions to a given forum or topic
     */
    public List findActivatedSubscriptionsByForumIdOrTopicId(Long forumId,
                                                             Long topicId);

    /**
     * Deletes too old non-activated forum subscriptions
     */
    public void deleteTimedOutForumSubscriptions();
}
